import Config from "./Config";
import Model from "./Model";
import MetaballMgr from "./MetaballMgr";

const { ccclass, property } = cc._decorator;

@ccclass
export default class GameDrop extends cc.Component {

    @property(cc.Node)
    world: cc.Node = null;

    @property(cc.Prefab)
    Ball: cc.Prefab = null;

    @property(cc.Prefab)
    Cup: cc.Prefab = null;

    @property([cc.Prefab])
    Bricks: cc.Prefab[] = [];

    @property(cc.Node)
    drawMgr: cc.Node = null;

    @property(cc.Prefab)
    TopUI: cc.Prefab = null;

    @property(cc.Prefab)
    BottomUI: cc.Prefab = null;

    @property(cc.Node)
    countDownNode: cc.Node = null
    countDownTime: number = 0

    @property(cc.Node)
    ground: cc.Node = null;

    @property(cc.Prefab)
    SmokeEff: cc.Prefab = null;

    cup: cc.Node;

    bricks: cc.Node[] = [];
    dynamicObjs:cc.Node[]=[];
    isChecking: boolean = false;

    lock: boolean = false;

    waters:cc.Node[]=[];

    onLoad() {
        Config.init()
        //开启物理效果
        cc.director.getPhysicsManager().enabled = true
        cc.director.getPhysicsManager().gravity = new cc.Vec2(0, -500);
        cc.director.getActionManager()['enabledAccumulator']=true;
        cc.director.getActionManager()['FIXED_TIME_STEP']=1/30;
        cc.director.getPhysicsManager()['VELOCITY_ITERATIONS']=8;
        // cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_jointBit | cc.PhysicsManager.DrawBits.e_shapeBit;
        this.createWorld()
        
        var top=cc.instantiate(this.TopUI)
        this.node.addChild(top)
        
        this.drawMgr.getComponent(MetaballMgr).waters=this.waters;
        this.node.getChildByName('gameTip').active=Model.game.selectedLevel==1
        console.log("@@@@@@@@@@@@@@@@@111")
    }

    start() {

    }
    createWorld() {
        //createCup
        var level = Model.game.selectedLevel;
        var data = Config.brickLevels[level];
        var cupPos = data[0]

        var cup = cc.instantiate(this.Cup);
        cup.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic;
        cup.x = cupPos[0]
        cup.y = cupPos[1]
        this.node.addChild(cup)
        cup.getComponent(cc.RigidBody).onBeginContact = (contact, selfCollider, otherCollider) => {
           // this.onBeginContact(contact, selfCollider, otherCollider)
        }



        var cupData = Config.cupDatas[1]
        for (var i = 0; i < cupData.polygonColliderList.length; i++) {
            var collider=cup.addComponent(cc.PhysicsPolygonCollider)
            collider.points = cupData.polygonColliderList[i]
            collider.density = 2
            collider.apply()
        }       
        this.cup = cup
        //添加水滴

        for (i = 0; i < 24; i++) {
            var ball = cc.instantiate(this.Ball);
            ball.x = cup.x + Math.random() * 8 - 16
            ball.y = cup.y + Math.random() * 50
            this.world.addChild(ball, -1)
            this.waters.push(ball)
        }

        //bricks
        for (var i = 1; i < data.length; i++) {
            var brickType = data[i][0]
            var brick = cc.instantiate(this.Bricks[brickType - 1])
            brick.x = data[i][1]
            brick.y = data[i][2]
            
            if (brickType == 1)//矩形
            {
                brick.setContentSize(cc.size(data[i][3], data[i][4]))
                brick.getComponent(cc.PhysicsBoxCollider).size = cc.size(cc.size(data[i][3], data[i][4]))
                brick.getComponent(cc.PhysicsBoxCollider).apply()
                

            }
            brick.angle = -data[i][5]
            this.node.addChild(brick)
            brick.on(cc.Node.EventType.TOUCH_START, this.onBrickTouch, this)
            this.bricks.push(brick);
            if (brick.getComponent(cc.RigidBody) != null) {
                if (brick.getComponent(cc.RigidBody).type == cc.RigidBodyType.Dynamic) {
                    this.dynamicObjs.push(brick);
                }
                brick.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static
            }
            brick.getComponent(cc.RigidBody).enabledContactListener=true
            brick.getComponent(cc.RigidBody).onBeginContact = (contact, selfCollider, otherCollider) => {
                 this.onBeginContact(contact, selfCollider, otherCollider)
             }
        }

        this.ground.getComponent(cc.RigidBody).onBeginContact = (contact, selfCollider, otherCollider) => {
            this.onBeginContact(contact, selfCollider, otherCollider)
        }

    }
    onBrickTouch(e) {
        if (this.lock) return
        var brick = (e.target as cc.Node)
        for (var i = 0; i < this.bricks.length; i++) {
            if (this.bricks[i] == brick) {
                this.bricks.splice(i, 1)
                break;
            }
        }
        for (var obj of this.dynamicObjs) {
            obj.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic;
        }
        this.dynamicObjs=[]
        brick.destroy()
    }


    update(dt) {
        this.drawMgr.getComponent(MetaballMgr).draw()
        if (this.lock) return
       // this.checkGame()
    }
    checkGame() {

        if (!this.isChecking) {
            this.isChecking = true
            console.log('检测');
            this.countDownTime = 3
            this.countDownNode.active = true;
            this.schedule(this.startCountDown, 1)
        }


    }

    startCountDown() {
        this.countDownNode.getChildByName('p0').active = false
        this.countDownNode.getChildByName('p1').active = false
        this.countDownNode.getChildByName('p2').active = false
        this.countDownNode.getChildByName('p3').active = false
        this.countDownTime--;

        this.countDownNode.getChildByName('p' + this.countDownTime).active = true
        if (this.countDownTime <= 0) {
            this.countDownNode.getChildByName('p0').active = false
            this.unschedule(this.startCountDown)
            //this.schedule(this.checkBallSleep, 0.016)
            Model.game.dropLevel++
            Model.game.win = true            
            this.showFace(2)
            this.scheduleOnce(this.delayShowEnd.bind(this), 1)
        }
    }
    delayShowEnd() {
        cc.director.loadScene('gameEnd')
    }
    showFace(type: number) {
        this.cup.getChildByName('facenormal').active = false;
        this.cup.getChildByName('facewin').active = false;
        this.cup.getChildByName('facelose').active = false;
        if (type == 2) {
            this.cup.getChildByName('facewin').active = true;
        } else if (type == 1) {
            this.cup.getChildByName('facelose').active = true;
        } else if (type == 0) {
            this.cup.getChildByName('facenormal').active = true;
        }
    }
    onBeginContact(contact, selfCollider, otherCollider) {
        
      //  console.log("onBeginContact:", otherCollider.node.name, " ", selfCollider.node.name);
        // console.log("onBeginContact", selfCollider.node.group, otherCollider.node.group);
        // console.log("onBeginContact", selfCollider.node.groupIndex, otherCollider.node.groupIndex);
        if(this.lock)return;

        if (selfCollider.node.name == 'ground' && otherCollider.node.name == 'Ball') {
            Model.game.win = false;
            
            this.showFace(1)
            this.scheduleOnce(this.delayShowEnd.bind(this), 1)
            this.lock = true

            for (var i = 0; i < this.waters.length; i++) {
                if (this.waters[i] == otherCollider.node) {
                    this.waters.splice(i, 1)
                    i--
                    this.createSmokeEff(otherCollider.node.x, otherCollider.node.y)
                    otherCollider.node.destroy()
                    break;
                }
            }
           
        }
        if(selfCollider.node.name == 'ground'&&otherCollider.node.name=='Cup2')
        {
            this.lock = true
            this.checkGame()
        }

        if(selfCollider.node.name.indexOf('brick')!=-1&&otherCollider.node.name=='Ball')
        {
            Model.game.win = false;
            
            this.showFace(1)
            this.scheduleOnce(this.delayShowEnd.bind(this), 1)
            this.lock = true
        }
    }
    createSmokeEff(x, y) {
        var eff = cc.instantiate(this.SmokeEff);
        eff.x = x;
        eff.y = y;
        this.node.addChild(eff);
    }
}
